package com.jeff.utils;

import java.util.ArrayList;
import java.util.List;

/**
 * author：duff
 * version：1.0.0
 * date：2017/8/31
 */
public class ArrayUtil {

    public static final String COMMA_SEPARATOR = ",";

    /**
     * get size of list
     *
     * @param <T>
     * @param list
     * @return if list is null or empty, return 0, else return {@link List#size()}.
     */
    public static <T> int getSize(List<T> list) {
        return list == null ? 0 : list.size();
    }

    /**
     * is null or its size is 0
     *
     * @param <T>
     * @param list
     * @return if list is null or its size is 0, return true, else return false.
     */
    public static <T> boolean isEmpty(List<T> list) {
        return (list == null || list.size() == 0);
    }

    public static <T> boolean isEmpty(T[] datas) {
        return datas == null || datas.length <= 0;
    }

    /**
     * join list to string, separator is ","
     *
     * @param list
     * @return join list to string, separator is ",". if list is empty, return ""
     */
    public static String join(List<String> list) {
        return join(list, COMMA_SEPARATOR);
    }

    /**
     * join list to string
     * <p>
     * <pre>
     * join(null, '#')     =   "";
     * join({}, '#')       =   "";
     * join({a,b,c}, ' ')  =   "abc";
     * join({a,b,c}, '#')  =   "a#b#c";
     * </pre>
     *
     * @param list
     * @param separator
     * @return join list to string. if list is empty, return ""
     */
    public static String join(List<String> list, char separator) {
        return join(list, new String(new char[]{separator}));
    }

    /**
     * join list to string. if separator is null, use {@link #COMMA_SEPARATOR}
     * <p>
     * <pre>
     * join(null, "#")     =   "";
     * join({}, "#$")      =   "";
     * join({a,b,c}, null) =   "a,b,c";
     * join({a,b,c}, "")   =   "abc";
     * join({a,b,c}, "#")  =   "a#b#c";
     * join({a,b,c}, "#$") =   "a#$b#$c";
     * </pre>
     *
     * @param list
     * @param separator
     * @return join list to string with separator. if list is empty, return ""
     */
    public static String join(List<String> list, String separator) {
        if (isEmpty(list)) {
            return "";
        }
        if (separator == null) {
            separator = COMMA_SEPARATOR;
        }

        StringBuilder joinStr = new StringBuilder();
        for (int i = 0; i < list.size(); i++) {
            joinStr.append(list.get(i));
            if (i != list.size() - 1) {
                joinStr.append(separator);
            }
        }
        return joinStr.toString();
    }

    /**
     * String list to string array
     *
     * @param list
     * @return
     */
    public static String[] list2StringArray(List<String> list) {
        if (isEmpty(list)) {
            return null;
        }
        int size = list.size();
        String[] strArray = new String[size];
        for (int i = 0; i < size; i++) {
            strArray[i] = list.get(i);
        }
        return strArray;
    }

    /**
     * String array to string list
     *
     * @param array
     * @return
     */
    public static List<String> stringArray2list(String[] array) {
        if (isEmpty(array)) {
            return null;
        }
        List<String> list = new ArrayList<>();
        for (int i = 0; i < array.length; i++) {
            list.add(array[i]);
        }
        return list;
    }

    /**
     * add distinct entry to list
     *
     * @param <T>
     * @param sourceList
     * @param entry
     * @return if entry already exist in sourceList, return false, else add it and return true.
     */
    public static <T> boolean addDistinctEntry(List<T> sourceList, T entry) {
        return (sourceList != null && !sourceList.contains(entry)) ? sourceList.add(entry) : false;
    }

    /**
     * add all distinct entry to list1 from list2
     *
     * @param <T>
     * @param sourceList
     * @param entryList
     * @return the count of entries be added
     */
    public static <T> int addDistinctList(List<T> sourceList, List<T> entryList) {
        if (sourceList == null || isEmpty(entryList)) {
            return 0;
        }

        int sourceCount = sourceList.size();
        for (T entry : entryList) {
            if (!sourceList.contains(entry)) {
                sourceList.add(entry);
            }
        }
        return sourceList.size() - sourceCount;
    }

    /**
     * remove duplicate entries in list
     *
     * @param <T>
     * @param list
     * @return the count of entries be removed
     */
    public static <T> int removeDuplicateItem(List<T> list) {
        if (isEmpty(list)) {
            return 0;
        }
        int count = list.size();
        int afterRemoveCount = list.size();
        for (int i = 0; i < afterRemoveCount; i++) {
            for (int j = (i + 1); j < afterRemoveCount; j++) {
                if (list.get(i).equals(list.get(j))) {
                    list.remove(j);
                    afterRemoveCount = list.size();
                    j--;
                }
            }
        }

        return count - list.size();
    }

    /**
     * invert list
     *
     * @param <T>
     * @param list
     * @return
     */
    public static <T> List<T> invertList(List<T> list) {
        if (isEmpty(list)) {
            return list;
        }

        List<T> invertList = new ArrayList<T>(list.size());
        for (int i = list.size() - 1; i >= 0; i--) {
            invertList.add(list.get(i));
        }
        return invertList;
    }


}
